//////////////////////////////////////////////////////////////////////////
//
// This file is a part of UKROP project.
// Copyright (c) Vladimir Gumenuk
//
// PROJECT:         Xort Custom Debug Engine
// FILE:            Engine.h : Declaration of the CEngine
// AUTHOR:          Vladimir Gumenuk
// DATE:            Dec-2012 -- Jan-2013
// MODIFICATIONS:
//
//////////////////////////////////////////////////////////////////////////

#pragma once
#include "resource.h"       // main symbols
#include "XortDebugEngine_i.h"

//////////////////////////////////////////////////////////////////////////
// CEngine
class ATL_NO_VTABLE CEngine :
	public CComObjectRootEx<CComSingleThreadModel>,
	public CComCoClass<CEngine, &CLSID_Engine>,
	public IDebugEngine2,
    public IDebugEngineLaunch2
{
public:
	CEngine();
    virtual ~CEngine();

DECLARE_REGISTRY_RESOURCEID(IDR_ENGINE)

BEGIN_COM_MAP(CEngine)
	COM_INTERFACE_ENTRY(IDebugEngine2)
    COM_INTERFACE_ENTRY(IDebugEngineLaunch2)
END_COM_MAP()

DECLARE_PROTECT_FINAL_CONSTRUCT()

	HRESULT FinalConstruct();
	void FinalRelease();

public:
    //////////////////////////////////////////////////////////// 
    //IDebugEngine2 
    STDMETHOD(EnumPrograms)( IEnumDebugPrograms2** ppEnum ); 
    STDMETHOD(Attach)( IDebugProgram2 **rgpPrograms, IDebugProgramNode2 **rgpProgramNodes, DWORD celtPrograms, IDebugEventCallback2 *pCallback, ATTACH_REASON dwReason ); 
    STDMETHOD(CreatePendingBreakpoint)( IDebugBreakpointRequest2 *pBPRequest, IDebugPendingBreakpoint2** ppPendingBP ); 
    STDMETHOD(SetException)( EXCEPTION_INFO* pException ); 
    STDMETHOD(RemoveSetException)( EXCEPTION_INFO* pException ); 
    STDMETHOD(RemoveAllSetExceptions)( REFGUID guidType ); 
    STDMETHOD(GetEngineId)( GUID *pguidEngine ); 
    STDMETHOD(DestroyProgram)( IDebugProgram2* pProgram ); 
    STDMETHOD(ContinueFromSynchronousEvent)( IDebugEvent2* pEvent ); 
    STDMETHOD(SetLocale)( WORD wLangID ); 
    STDMETHOD(SetRegistryRoot)( LPCOLESTR pszRegistryRoot ); 
    STDMETHOD(SetMetric)( LPCOLESTR pszMetric, VARIANT varValue ); 
    STDMETHOD(CauseBreak)(); 

    //////////////////////////////////////////////////////////// 
    // IDebugEngineLaunch2 
    STDMETHOD(LaunchSuspended)( 
        __RPC__in_opt LPCOLESTR pszServer,
        __RPC__in_opt IDebugPort2 *pPort,
        __RPC__in_opt LPCOLESTR pszExe,
        __RPC__in_opt LPCOLESTR pszArgs,
        __RPC__in_opt LPCOLESTR pszDir,
        __RPC__in_opt BSTR bstrEnv,
        __RPC__in_opt LPCOLESTR pszOptions,
        LAUNCH_FLAGS dwLaunchFlags,
        DWORD hStdInput,
        DWORD hStdOutput,
        DWORD hStdError,
        __RPC__in_opt IDebugEventCallback2 *pCallback,
        __RPC__deref_out_opt IDebugProcess2 **ppProcess );

    STDMETHOD(ResumeProcess)( __RPC__in_opt IDebugProcess2 *pProcess );
    STDMETHOD(CanTerminateProcess)( __RPC__in_opt IDebugProcess2 *pProcess );
    STDMETHOD(TerminateProcess)( __RPC__in_opt IDebugProcess2 *pProcess );

private:
    BOOL isMyProcess( IDebugProcess2 *pProcess );

    CComPtr<IDebugPortNotify2>      m_spPortNotify;// Notification port

    CComPtr<IDebugProgram2>         m_spProgram;  // our program
    CComPtr<IDebugProcess2>         m_spProcess;  // our virtual process
    WORD                            m_wLocale;
    CComBSTR                        m_bsRegistryRoot;
    DWORD                           m_hStdInput;  // supplied by IVsDebbuger to redirect program output
    DWORD                           m_hStdOutput;
    DWORD                           m_hStdError;

    BOOL                            m_bTraceSettings; // metric
};

OBJECT_ENTRY_AUTO(__uuidof(Engine), CEngine)
